import random
import pandas as pd
from faker import Faker
from datetime import datetime, timedelta
import os

# 创建 Faker 实例，用于生成随机数据
fake = Faker('zh_CN')

def generate_products(num_products=1000):
    """生成商品信息表"""
    products = []
    categories = ['电子产品', '服装鞋帽', '家居用品', '美妆个护', '母婴用品', '食品饮料', '图书音像', '运动户外']
    brands = ['华为', '小米', '苹果', '三星', '耐克', '阿迪达斯', '优衣库', '宝洁', '可口可乐', '海尔']

    for product_id in range(1, num_products + 1):
        category = random.choice(categories)
        brand = random.choice(brands)
        product_name = f"{brand} {category}{random.randint(1, 100)}"
        price = round(random.uniform(10, 10000), 2)
        original_price = round(price * random.uniform(1, 1.5), 2)
        sales_volume = random.randint(0, 100000)
        rating = round(random.uniform(1, 5), 1)
        review_count = random.randint(0, 5000)
        inventory = random.randint(0, 1000)
        is_on_sale = random.random() > 0.7
        is_new = random.random() > 0.8
        is_hot = random.random() > 0.8

        products.append({
            'product_id': product_id,
            'product_name': product_name,
            'category': category,
            'brand': brand,
            'price': price,
            'original_price': original_price,
            'sales_volume': sales_volume,
            'rating': rating,
            'review_count': review_count,
            'inventory': inventory,
            'is_on_sale': is_on_sale,
            'is_new': is_new,
            'is_hot': is_hot,
            'created_at': fake.date_time_between(start_date='-1y', end_date='now')
        })

    return pd.DataFrame(products)


def generate_users(num_users=500):
    """生成用户信息表"""
    users = []

    for user_id in range(1, num_users + 1):
        gender = random.choice(['男', '女'])
        age = random.randint(18, 70)
        city = fake.city()
        membership_level = random.choice(['普通会员', '铜牌会员', '银牌会员', '金牌会员', '钻石会员'])
        registration_date = fake.date_time_between(start_date='-3y', end_date='now')
        last_login = registration_date + timedelta(days=random.randint(0, 365))

        users.append({
            'user_id': user_id,
            'username': fake.user_name(),
            'gender': gender,
            'age': age,
            'city': city,
            'membership_level': membership_level,
            'registration_date': registration_date,
            'last_login': last_login,
            'search_frequency': random.randint(1, 30)  # 平均每月搜索次数
        })

    return pd.DataFrame(users)


def generate_search_keywords(num_keywords=200):
    """生成搜索关键词表"""
    # 热门搜索词
    popular_keywords = [
        "手机", "笔记本电脑", "运动鞋", "连衣裙", "空调", "洗发水", "婴儿奶粉", "猫粮", "蓝牙耳机", "智能手表",
        "卫衣", "牛仔裤", "冰箱", "口红", "面膜", "儿童玩具", "啤酒", "书籍", "篮球", "沙发"
    ]

    # 组合生成更多关键词
    keywords = []
    for _ in range(num_keywords):
        if random.random() < 0.6:  # 60%的概率使用热门关键词
            keyword = random.choice(popular_keywords)
            # 添加一些修饰词
            if random.random() < 0.5:
                prefix = random.choice(["新款", "2025年新款", "夏季", "冬季", "男士", "女士", "儿童", "家用", "商用"])
                keyword = f"{prefix}{keyword}"
        else:  # 40%的概率生成随机关键词
            keyword = fake.sentence(nb_words=2, variable_nb_words=True).replace(' ', '').replace('.', '')

        keywords.append({
            'keyword_id': len(keywords) + 1,
            'keyword_text': keyword,
            'search_volume': random.randint(100, 1000000),  # 搜索量
            'is_popular': random.random() > 0.8,
            'category': random.choice(
                ['电子产品', '服装鞋帽', '家居用品', '美妆个护', '母婴用品', '食品饮料', '图书音像', '运动户外',
                 '其他'])
        })

    return pd.DataFrame(keywords)


def generate_search_records(users_df, keywords_df, products_df, num_searches=5000):
    """生成搜索记录表"""
    search_records = []

    for search_id in range(1, num_searches + 1):
        # 随机选择用户
        user = users_df.iloc[random.randint(0, len(users_df) - 1)]

        # 根据用户搜索频率调整搜索时间分布
        days_ago = min(random.expovariate(1 / user['search_frequency']), 90)
        search_time = datetime.now() - timedelta(days=days_ago)

        # 随机选择关键词
        # 热门关键词更有可能被选中
        if random.random() < 0.7:  # 70%的概率选择热门关键词
            popular_keywords = keywords_df[keywords_df['is_popular'] == True]
            keyword = popular_keywords.iloc[random.randint(0, len(popular_keywords) - 1)]
        else:
            keyword = keywords_df.iloc[random.randint(0, len(keywords_df) - 1)]

        # 基于关键词类别筛选相关产品
        category = keyword['category']
        if category == '其他':
            relevant_products = products_df.sample(min(20, len(products_df)))
        else:
            relevant_products = products_df[products_df['category'] == category].sample(
                min(20, len(products_df[products_df['category'] == category])))

        # 生成搜索结果（随机选择3-10个产品）
        num_results = random.randint(3, 10)
        search_results = relevant_products.sample(num_results)['product_id'].tolist()

        # 用户是否点击了搜索结果
        has_click = random.random() > 0.3

        if has_click:
            # 用户点击的产品（从搜索结果中选择）
            clicked_product = random.choice(search_results)
            # 点击时间（搜索后几秒到几分钟不等）
            click_time = search_time + timedelta(seconds=random.randint(1, 300))
            # 用户是否加入购物车
            added_to_cart = random.random() > 0.7 if has_click else False
            # 用户是否购买
            purchased = random.random() > 0.8 if added_to_cart else False
        else:
            clicked_product = None
            click_time = None
            added_to_cart = False
            purchased = False

        search_records.append({
            'search_id': search_id,
            'user_id': user['user_id'],
            'keyword_id': keyword['keyword_id'],
            'search_time': search_time,
            'search_results': search_results,
            'has_click': has_click,
            'clicked_product_id': clicked_product,
            'click_time': click_time,
            'added_to_cart': added_to_cart,
            'purchased': purchased,
            'search_duration': random.randint(5, 300),  # 搜索持续时间（秒）
            'device': random.choice(['PC', '手机', '平板']),
            'platform': random.choice(['淘宝', '天猫', '1688']),
            'is_mobile': random.random() > 0.3
        })

    return pd.DataFrame(search_records)


def generate_product_reviews(users_df, products_df, num_reviews=3000):
    """生成商品评价表"""
    reviews = []

    for review_id in range(1, num_reviews + 1):
        user = users_df.iloc[random.randint(0, len(users_df) - 1)]
        product = products_df.iloc[random.randint(0, len(products_df) - 1)]

        # 评价时间（购买后1-30天）
        review_time = datetime.now() - timedelta(days=random.randint(1, 30))

        # 评分（根据商品平均评分调整）
        base_rating = product['rating']
        rating = max(1, min(5, round(base_rating + random.uniform(-1, 1), 1)))

        # 评价内容
        review_text = fake.paragraph(nb_sentences=3, variable_nb_sentences=True)

        # 是否有图片
        has_pictures = random.random() > 0.6
        if has_pictures:
            pictures_count = random.randint(1, 9)
            pictures = [f"https://picsum.photos/400/400?random={review_id}_{i}" for i in range(pictures_count)]
        else:
            pictures = []

        # 是否是追评
        is_followup = random.random() > 0.8
        if is_followup:
            followup_days = random.randint(7, 60)
            followup_text = fake.paragraph(nb_sentences=2, variable_nb_sentences=True)
            followup_time = review_time + timedelta(days=followup_days)
        else:
            followup_text = None
            followup_time = None

        # 是否是优质评价
        is_high_quality = random.random() > 0.9 if rating >= 4 else False

        reviews.append({
            'review_id': review_id,
            'user_id': user['user_id'],
            'product_id': product['product_id'],
            'rating': rating,
            'review_text': review_text,
            'review_time': review_time,
            'has_pictures': has_pictures,
            'pictures': pictures,
            'is_followup': is_followup,
            'followup_text': followup_text,
            'followup_time': followup_time,
            'useful_count': random.randint(0, 500),  # 有用数
            'reply_count': random.randint(0, 10),  # 回复数
            'is_high_quality': is_high_quality
        })

    return pd.DataFrame(reviews)


def save_to_csv(products_df, users_df, keywords_df, search_records_df, reviews_df, output_dir='../mock_data'):
    """将数据保存为CSV文件"""
    os.makedirs(output_dir, exist_ok=True)

    products_df.to_csv(f"{output_dir}/products.csv", index=False, encoding='utf-8-sig')
    users_df.to_csv(f"{output_dir}/users.csv", index=False, encoding='utf-8-sig')
    keywords_df.to_csv(f"{output_dir}/search_keywords.csv", index=False, encoding='utf-8-sig')
    search_records_df.to_csv(f"{output_dir}/search_records.csv", index=False, encoding='utf-8-sig')
    reviews_df.to_csv(f"{output_dir}/product_reviews.csv", index=False, encoding='utf-8-sig')

    print(f"数据已成功保存到 {output_dir} 目录下")


if __name__ == "__main__":
    # 生成数据
    print("正在生成商品数据...")
    products = generate_products(num_products=1000)

    print("正在生成用户数据...")
    users = generate_users(num_users=500)

    print("正在生成搜索关键词数据...")
    keywords = generate_search_keywords(num_keywords=200)

    print("正在生成搜索记录数据...")
    search_records = generate_search_records(users, keywords, products, num_searches=5000)

    print("正在生成商品评价数据...")
    reviews = generate_product_reviews(users, products, num_reviews=3000)

    # 保存数据
    save_to_csv(products, users, keywords, search_records, reviews)